﻿Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Design
Imports System.IO
Imports System.Resources
Imports System.Web
Imports System.Workflow.ComponentModel.Design

Namespace System.Workflow.Activities
    Friend Class StateMachineTheme
        Inherits CompositeDesignerTheme
        ' Methods
        Public Sub New(ByVal theme As WorkflowTheme)
            MyBase.New(theme)
            Me._connectorColor = Color.Black
            Me._connectorSize = New Size(20, 20)
        End Sub

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try 
                If (Not Me._connectorPen Is Nothing) Then
                    Me._connectorPen.Dispose
                    Me._connectorPen = Nothing
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        Friend Shared Function GetImageFromPath(ByVal designerTheme As DesignerTheme, ByVal directory As String, ByVal path As String) As Image
            Dim bitmap As Bitmap = Nothing
            If (path.Contains(Path.DirectorySeparatorChar.ToString) AndAlso (directory.Length > 0)) Then
                Dim str As String = HttpUtility.UrlDecode(New Uri(New Uri(directory), path).LocalPath)
                If File.Exists(str) Then
                    Try 
                        bitmap = New Bitmap(str)
                    Catch obj1 As Object
                    End Try
                End If
            ElseIf (Not designerTheme.DesignerType Is Nothing) Then
                Dim length As Integer = path.LastIndexOf("."c)
                If (length > 0) Then
                    Dim baseName As String = path.Substring(0, length)
                    Dim name As String = path.Substring((length + 1))
                    If (((Not baseName Is Nothing) AndAlso (baseName.Length > 0)) AndAlso ((Not name Is Nothing) AndAlso (name.Length > 0))) Then
                        Try 
                            Dim manager As New ResourceManager(baseName, designerTheme.DesignerType.Assembly)
                            bitmap = [TryCast](manager.GetObject(name),Bitmap)
                        Catch obj2 As Object
                        End Try
                    End If
                End If
            End If
            If (Not bitmap Is Nothing) Then
                bitmap.MakeTransparent(DR.TransparentColor)
            End If
            Return bitmap
        End Function

        Friend Shared Function GetRelativePath(ByVal pathFrom As String, ByVal pathTo As String) As String
            Dim uri As New Uri(pathFrom)
            Dim str As String = Uri.UnescapeDataString(uri.MakeRelativeUri(New Uri(pathTo)).ToString).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)
            If Not str.Contains(Path.DirectorySeparatorChar.ToString) Then
                str = ("." & Path.DirectorySeparatorChar & str)
            End If
            Return str
        End Function

        Friend Shared Function IsValidImageResource(ByVal designerTheme As DesignerTheme, ByVal directory As String, ByVal path As String) As Boolean
            Dim image As Image = StateMachineTheme.GetImageFromPath(designerTheme, directory, path)
            Dim flag As Boolean = (Not image Is Nothing)
            If (Not image Is Nothing) Then
                image.Dispose
            End If
            Return flag
        End Function


        ' Properties
        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property CompletedStateDesignerImage As Image
            Get
                If ((Me._completedStateDesignerImage Is Nothing) AndAlso Not String.IsNullOrEmpty(Me._completedStateDesignerImagePath)) Then
                    Me._completedStateDesignerImage = StateMachineTheme.GetImageFromPath(Me, MyBase.ContainingTheme.ContainingFileDirectory, Me._completedStateDesignerImagePath)
                End If
                Return Me._completedStateDesignerImage
            End Get
        End Property

        <Editor(GetType(ImageBrowserEditor), GetType(UITypeEditor)), SRCategory("ForegroundCategory"), SRDescription("CompletedStateImagePathDescription")> _
        Public Overridable Property CompletedStateDesignerImagePath As String
            Get
                Return Me._completedStateDesignerImagePath
            End Get
            Set(ByVal value As String)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly"))
                End If
                If (((Not value Is Nothing) AndAlso (value.Length > 0)) AndAlso (value.Contains(Path.DirectorySeparatorChar.ToString) AndAlso Path.IsPathRooted(value))) Then
                    value = StateMachineTheme.GetRelativePath(MyBase.ContainingTheme.ContainingFileDirectory, value)
                    If Not StateMachineTheme.IsValidImageResource(Me, MyBase.ContainingTheme.ContainingFileDirectory, value) Then
                        Throw New InvalidOperationException(DR.GetString("Error_InvalidImageResource"))
                    End If
                End If
                Me._completedStateDesignerImagePath = value
                If (Not Me._completedStateDesignerImage Is Nothing) Then
                    Me._completedStateDesignerImage.Dispose
                    Me._completedStateDesignerImage = Nothing
                End If
            End Set
        End Property

        <SRDescription("ConnectorColorDescription"), SRCategory("ForegroundCategory")> _
        Public Property ConnectorColor As Color
            Get
                Return Me._connectorColor
            End Get
            Set(ByVal value As Color)
                Me._connectorColor = value
            End Set
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property ConnectorPen As Pen
            Get
                If (Me._connectorPen Is Nothing) Then
                    Me._connectorPen = New Pen(Me._connectorColor, CSng(MyBase.BorderWidth))
                End If
                Return Me._connectorPen
            End Get
        End Property

        Public Overrides ReadOnly Property ConnectorSize As Size
            Get
                Return Me._connectorSize
            End Get
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property InitialStateDesignerImage As Image
            Get
                If ((Me._initialStateDesignerImage Is Nothing) AndAlso Not String.IsNullOrEmpty(Me._initialStateDesignerImagePath)) Then
                    Me._initialStateDesignerImage = StateMachineTheme.GetImageFromPath(Me, MyBase.ContainingTheme.ContainingFileDirectory, Me._initialStateDesignerImagePath)
                End If
                Return Me._initialStateDesignerImage
            End Get
        End Property

        <SRCategory("ForegroundCategory"), Editor(GetType(ImageBrowserEditor), GetType(UITypeEditor)), SRDescription("InitialStateImagePathDescription")> _
        Public Overridable Property InitialStateDesignerImagePath As String
            Get
                Return Me._initialStateDesignerImagePath
            End Get
            Set(ByVal value As String)
                If MyBase.ReadOnly Then
                    Throw New InvalidOperationException(DR.GetString("ThemePropertyReadOnly"))
                End If
                If (((Not value Is Nothing) AndAlso (value.Length > 0)) AndAlso (value.Contains(Path.DirectorySeparatorChar.ToString) AndAlso Path.IsPathRooted(value))) Then
                    value = StateMachineTheme.GetRelativePath(MyBase.ContainingTheme.ContainingFileDirectory, value)
                    If Not StateMachineTheme.IsValidImageResource(Me, MyBase.ContainingTheme.ContainingFileDirectory, value) Then
                        Throw New InvalidOperationException(DR.GetString("Error_InvalidImageResource"))
                    End If
                End If
                Me._initialStateDesignerImagePath = value
                If (Not Me._initialStateDesignerImage Is Nothing) Then
                    Me._initialStateDesignerImage.Dispose
                    Me._initialStateDesignerImage = Nothing
                End If
            End Set
        End Property


        ' Fields
        Private _completedStateDesignerImage As Image
        Private _completedStateDesignerImagePath As String
        Private _connectorColor As Color
        Private _connectorPen As Pen
        Private _connectorSize As Size
        Private _initialStateDesignerImage As Image
        Private _initialStateDesignerImagePath As String
        Friend Const DefaultThemeFileExtension As String = "*.wtm"
    End Class
End Namespace

